home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 1 / BBS in a box - Trilogy I.iso / Files / Publish / Photoshop / Plug-in Modules / Code / Dissolve.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-26  |  8.6 KB  |  448 lines  |  [TEXT/MPS ]

  1. /*
  2.     File: Dissolve.c
  3.  
  4.     Copyright 1990 by Thomas Knoll.
  5.     Copyright 1993 by Adobe Systems, Inc.
  6.  
  7.     C source file for Dissolve example.
  8. */
  9.  
  10. #include <Types.h>
  11. #include <Memory.h>
  12. #include <Resources.h>
  13. #include <QuickDraw.h>
  14. #include <Dialogs.h>
  15. #include <OSUtils.h>
  16. #include <Packages.h>
  17. #include <Errors.h>
  18. #include <ToolUtils.h>
  19.  
  20. #include "PITypes.h"
  21. #include "PIGeneral.h"
  22. #include "PIFilter.h"
  23.  
  24. #include "DialogUtilities.h"
  25. #include "PIUtilities.h"
  26.  
  27. #ifdef THINK_C
  28.  
  29. #define ENTRYPOINT main
  30.  
  31. #endif
  32.  
  33. /*****************************************************************************/
  34.  
  35. typedef struct TParameters
  36.     {
  37.     short percent;
  38.     } TParameters, *PParameters, **HParameters;
  39.  
  40. /*****************************************************************************/
  41.  
  42. typedef struct Globals
  43.     {
  44.     short result;
  45.     FilterRecord *stuff;
  46.     } Globals, *GPtr, **GHdl;
  47.     
  48. #define gResult ((**globals).result)
  49. #define gStuff  ((**globals).stuff)
  50.  
  51. /*****************************************************************************/
  52.  
  53. void InitGlobals (GHdl globals);
  54.  
  55. void DoAbout (GHdl globals);
  56. void DoParameters (GHdl globals);
  57. void DoPrepare (GHdl globals);
  58. void DoStart (GHdl globals);
  59. void DoContinue (GHdl globals);
  60. void DoFinish (GHdl globals);
  61.  
  62. /*****************************************************************************/
  63.  
  64. /* All calls to the plug-in module come through this routine. It must be
  65.    placed first in the resource. To achieve this, most development systems
  66.    require that this be the first routine in the source. */
  67.  
  68. pascal void ENTRYPOINT (short selector,
  69.                         FilterRecord *stuff,
  70.                         long *data,
  71.                         short *result)
  72.     {
  73.     
  74.     GHdl globals;
  75.     
  76.     if (!*data)
  77.         {
  78.  
  79.         *data = (long) NewHandle (sizeof (Globals));
  80.         
  81.         if (!*data)
  82.             {
  83.             *result = memFullErr;
  84.             return;
  85.             }
  86.             
  87.         InitGlobals ((GHdl) *data);
  88.         
  89.         }
  90.         
  91.     globals = (GHdl) *data;
  92.         
  93.     gStuff = stuff;
  94.     gResult = noErr;
  95.         
  96.     switch (selector)
  97.         {
  98.         
  99.         case filterSelectorAbout:
  100.             DoAbout (globals);
  101.             break;
  102.             
  103.         case filterSelectorParameters:
  104.             DoParameters (globals);
  105.             break;
  106.             
  107.         case filterSelectorPrepare:
  108.             DoPrepare (globals);
  109.             break;
  110.         
  111.         case filterSelectorStart:
  112.             DoStart (globals);
  113.             break;
  114.         
  115.         case filterSelectorContinue:
  116.             DoContinue (globals);
  117.             break;
  118.         
  119.         case filterSelectorFinish:
  120.             DoFinish (globals);
  121.             break;
  122.             
  123.         default:
  124.             gResult = filterBadParameters;
  125.         
  126.         }
  127.         
  128.     *result = gResult;
  129.         
  130.     }
  131.  
  132. /*****************************************************************************/
  133.  
  134. void InitGlobals (GHdl globals)
  135.     {
  136.     
  137.     #pragma unused (globals)
  138.     
  139.     /* None of the globals requires initialization. */
  140.     
  141.     }
  142.  
  143. /*****************************************************************************/
  144.  
  145. /* Displays the about dialog box for the plug-in module. */
  146.  
  147. void DoAbout (GHdl globals)
  148.     {
  149.  
  150.     #pragma unused (globals)
  151.     
  152.     #define dialogID 16000
  153.     
  154.     ShowAbout (dialogID);
  155.  
  156.     #undef dialogID
  157.  
  158.     }
  159.  
  160. /*****************************************************************************/
  161.  
  162. /* Asks the user for the plug-in filter module's parameters. Note that
  163.    the image size information is not yet defined at this point. Also, do
  164.    not assume that the calling program will call this routine every time the
  165.    filter is run (it may save the data held by the parameters handle in
  166.    a macro file). */
  167.  
  168. void DoParameters (GHdl globals)
  169.  
  170.     {
  171.  
  172.     #define dialogID    16001
  173.     #define hookItem    3
  174.     #define percentItem 4
  175.     
  176.     long x;
  177.     short item;
  178.     DialogPtr dp;
  179.     DialogTHndl dt;
  180.  
  181.     if (!gStuff->parameters)
  182.         {
  183.  
  184.         gStuff->parameters = NewHandle ((long) sizeof (TParameters));
  185.  
  186.         if (!gStuff->parameters)
  187.             {
  188.             gResult = memFullErr;
  189.             return;
  190.             }
  191.  
  192.         ((PParameters) *gStuff->parameters)->percent = 50;
  193.  
  194.         }
  195.  
  196.     dt = (DialogTHndl) GetResource ('DLOG', dialogID);
  197.     HNoPurge ((Handle) dt);
  198.     
  199.     CenterDialog (dt);
  200.     SetUpMoveableModal (dt, gStuff->hostSig);
  201.  
  202.     dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
  203.  
  204.     SetOutlineOKHook (dp, hookItem);
  205.     
  206.     StuffNumber (dp,
  207.                  percentItem,
  208.                  ((PParameters) *gStuff->parameters)->percent);
  209.     
  210.     SetArrowCursor ();
  211.  
  212.     SelectTextItem (dp, percentItem); 
  213.  
  214.     do
  215.         {
  216.         
  217.         MoveableModalDialog (dp, gStuff->processEvent, nil, &item);
  218.  
  219.         if (item == ok)
  220.             {
  221.  
  222.             if (!FetchNumber (dp, percentItem, 1, 99, &x))
  223.                 item = 0;
  224.  
  225.             }
  226.  
  227.         }
  228.     while (item != ok && item != cancel);
  229.  
  230.     DisposDialog (dp);
  231.     HPurge ((Handle) dt);
  232.  
  233.     if (item == cancel)
  234.         {
  235.         gResult = 1;
  236.         return;
  237.         }
  238.  
  239.     ((PParameters) *gStuff->parameters)->percent = x;
  240.  
  241.     #undef dialogID
  242.     #undef hookItem
  243.     #undef percentItem
  244.  
  245.     }
  246.  
  247. /*****************************************************************************/
  248.  
  249. /* Prepare to filter an image.    If the plug-in filter needs a large amount
  250.    of buffer memory, this routine should set the bufferSpace field to the
  251.    number of bytes required. */
  252.  
  253. void DoPrepare (GHdl globals)
  254.     {
  255.     
  256.     gStuff->bufferSpace = 0;
  257.     
  258.     }
  259.  
  260. /*****************************************************************************/
  261.  
  262. void DoInitialRect (GHdl globals);
  263. Boolean DoNextRect (GHdl globals);
  264.  
  265. void DoFilterRect (GHdl globals);
  266.  
  267. /*****************************************************************************/
  268.  
  269. /* Requests pointer to the first part of the image to be filtered. */
  270.  
  271. void DoStart (GHdl globals)
  272.     {
  273.     
  274.     DoInitialRect (globals);
  275.  
  276.     }
  277.  
  278. /*****************************************************************************/
  279.  
  280. /* Filters the area and requests the next area. */
  281.  
  282. void DoContinue (GHdl globals)
  283.     {
  284.     
  285.     if (TestAbort ())
  286.         {
  287.         gResult = 1;
  288.         return;
  289.         }
  290.         
  291.     DoFilterRect (globals);
  292.     
  293.     if (!DoNextRect (globals))
  294.         {
  295.         SetRect (&gStuff->inRect, 0, 0, 0, 0);
  296.         SetRect (&gStuff->outRect, 0, 0, 0, 0);
  297.         }
  298.  
  299.     }
  300.  
  301. /*****************************************************************************/
  302.  
  303. /* Requests first part of the image to be filtered. */
  304.  
  305. void DoInitialRect (GHdl globals)
  306.     {
  307.  
  308.     gStuff->inRect          = gStuff->filterRect;
  309.     gStuff->inRect.bottom = gStuff->inRect.top + 1;
  310.  
  311.     gStuff->inLoPlane = 0;
  312.     gStuff->inHiPlane = gStuff->planes - 1;
  313.     
  314.     gStuff->outRect = gStuff->inRect;
  315.  
  316.     gStuff->outLoPlane = gStuff->inLoPlane;
  317.     gStuff->outHiPlane = gStuff->inHiPlane;
  318.  
  319.     }
  320.  
  321. /*****************************************************************************/
  322.  
  323. /* Request the next area. */
  324.  
  325. Boolean DoNextRect (GHdl globals)
  326.     {
  327.  
  328.     gStuff->inRect.top      = gStuff->inRect.top      + 1;
  329.     gStuff->inRect.bottom = gStuff->inRect.bottom + 1;
  330.     
  331.     gStuff->outRect = gStuff->inRect;
  332.  
  333.     return gStuff->inRect.top < gStuff->filterRect.bottom;
  334.  
  335.     }
  336.  
  337. /*****************************************************************************/
  338.  
  339. /* Filter the area. */
  340.  
  341. void DoFilterRect (GHdl globals)
  342.     {
  343.  
  344.     short rand;
  345.     short count;
  346.     short plane;
  347.     short percent;
  348.     unsigned char *srcPtr;
  349.     unsigned char *dstPtr;
  350.  
  351.     UpdateProgress ((long) gStuff->inRect.top - gStuff->filterRect.top,
  352.                     (long) gStuff->filterRect.bottom - gStuff->filterRect.top);
  353.  
  354.     percent = ((PParameters) *gStuff->parameters)->percent;
  355.  
  356.     srcPtr = (unsigned char *) gStuff->inData;
  357.     dstPtr = (unsigned char *) gStuff->outData;
  358.  
  359.     count = gStuff->filterRect.right - gStuff->filterRect.left;
  360.  
  361.     while (count--)
  362.         {
  363.  
  364.         rand = Random ();
  365.         rand = (rand < 0 ? -rand : rand);
  366.  
  367.         if (rand % 100 < percent)
  368.             {
  369.  
  370.             for (plane = 0; plane < gStuff->planes; ++plane)
  371.                 *(dstPtr++) = plane < 4 ? gStuff->backColor [plane]
  372.                                         : 255;
  373.  
  374.             srcPtr += gStuff->planes;
  375.  
  376.             }
  377.  
  378.         else
  379.             for (plane = 0; plane < gStuff->planes; ++plane)
  380.                 *(dstPtr++) = *(srcPtr++);
  381.  
  382.         }
  383.  
  384.     }
  385.  
  386. /*****************************************************************************/
  387.  
  388. /* This routine will always be called if DoStart does not return an error
  389.    (even if DoContinue returns an error or the user aborts the operation).
  390.    This allows the module to perform any needed cleanup.  None is required
  391.    in this example. */
  392.  
  393. void DoFinish (GHdl globals)
  394.     {
  395.     
  396.     /* We will attempt to add a resource showing that we made this change.
  397.        Unfortunately, we will not be able to remove this resource if the
  398.        user chooses undo.  This could change in the future, so do not
  399.        count on it. */
  400.     
  401.     Str255 string;
  402.     short stringLength;
  403.     short numLength;
  404.     Handle h;
  405.     
  406.     if (!ResourceProcsAvailable (NULL))
  407.         return;
  408.         
  409.     GetIndString (string, 16000, 1);
  410.         
  411.     stringLength = (unsigned char) (string [0]);
  412.     
  413.     h = PINewHandle (stringLength);
  414.     
  415.     if (!h)
  416.         return;
  417.         
  418.     BlockMove (&(string [1]), PILockHandle (h, FALSE), stringLength); 
  419.  
  420.     PIUnlockHandle (h);
  421.     
  422.     NumToString (((PParameters) *gStuff->parameters)->percent, string);
  423.     
  424.     numLength = (unsigned char) string [0];
  425.     
  426.     if (PISetHandleSize (h, stringLength + numLength + 1) == noErr)
  427.         {
  428.         
  429.         BlockMove (&(string [1]),
  430.                    PILockHandle (h, FALSE) + stringLength,
  431.                    numLength);
  432.         
  433.         PIUnlockHandle (h);
  434.         
  435.         stringLength += numLength;
  436.         
  437.         (*h) [stringLength] = '%';
  438.         
  439.         (void) AddPIResource ('hist', h);
  440.         
  441.         }
  442.         
  443.     PIDisposeHandle (h);
  444.     
  445.     }
  446.  
  447. /*****************************************************************************/
  448.